package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.feign.ArticleFeign;
import com.heima.media.service.*;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

//新建自动审核
@Service
public class AuditServiceImpl implements IAuditService {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    @Lazy   //延迟加载 避免循环依赖
    private IWmNewsService wmNewsService;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService wmChannelService;


    @Override
    @Async  //异步调用
    public void audit(WmNews wmNews) {
        //自理敏感词  放在阿里的前面
        boolean isPass=true;
        isPass=checkSensitive(wmNews);
        if(!isPass) return;
        //审核文章的文本
         isPass=checkText(wmNews);
        if(!isPass) return;
        //审核文章的图片
        isPass=checkImage(wmNews);
        if(!isPass) return;
        //判断当前是否到达发布时间   入过当前的时间大于应法时间则为已到达发布时间
        if (System.currentTimeMillis()>wmNews.getPublishTime().getTime()){
        //当到达时间是发布 远程保存
            saveArticle(wmNews);
            Long articleId = saveArticle(wmNews);
            wmNews.setArticleId(articleId);
            wmNews.setStatus(9);
            wmNewsService.updateById(wmNews);
        }else {
            //时辰未到  ,先修改下文章的状态
            wmNews.setStatus(8);
            //放到延时队列中
            RBlockingQueue<Object> blockingQueue = redissonClient.getBlockingQueue("test-dqueue");
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);
            //预计发布时间减去当前的时间
            long time = wmNews.getPublishTime().getTime() - System.currentTimeMillis();
            //getTime() 毫秒
            delayedQueue.offer(wmNews.getId(),time, TimeUnit.MINUTES);
            //
            wmNewsService.updateById(wmNews);
        }

        //审核通过时

    }
    @Autowired
    private IWmSensitiveService wmSensitiveService;
    private boolean checkSensitive(WmNews wmNews) {
        String text =  wmNews.getTitle();
        //从Content中提取文本
        List<ContentDto> contentDtos =  JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }   //text 中包含文章和标题
   //初始化DFA算法的map
        List<WmSensitive> wmSensitiveList = wmSensitiveService.list();
        List<String> sensitiveWords = new ArrayList<>();
        for (WmSensitive sensitive : wmSensitiveList) {
            sensitiveWords.add(sensitive.getSensitives());
        }
        SensitiveWordUtil.initMap(sensitiveWords);
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
        if (stringIntegerMap.size()>0) {
            //审核驳回
            Set<String> strings = stringIntegerMap.keySet();
            String reason = String.join(",", strings);
            wmNews.setStatus(2);
            wmNews.setReason("敏感词审核未通过，原因是包含以下敏感词：" +reason); //审核不通过或需要人工审核的原因
            wmNewsService.updateById(wmNews);
            return false;
        }else{
            return true;
        }
    }

    @Override//测试用
    public void audit(Integer newsId) {
        WmNews wmNews = wmNewsService.getById(newsId);
        audit(wmNews);

    }

    //远程调用保存文章信息
    public Long saveArticle(WmNews wmNews) {
        ArticleDto dto = new ArticleDto();
        articleFeign.saveArticle(dto);
        dto.setContent(wmNews.getContent());
      //  dto.setId();
        dto.setTitle(wmNews.getTitle());
        //自媒体用户中是有App文章作者
        //根据当前自媒体人的id查询自媒体人对象
        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        dto.setAuthorId(wmUser.getApAuthorId());  //文章作者的id
        dto.setAuthorName(wmUser.getName());
        //App文章的作者
        dto.setChannelId(wmNews.getChannelId());
        WmChannel wmChannel = wmChannelService.getById(wmNews.getChannelId());
        dto.setChannelName(wmChannel.getName());
        dto.setLayout(wmNews.getType());
        dto.setFlag(0); //(value = "文章标记            0 普通文章            1 热点文章            2 置顶文章            3 精品文章            4 大V 文章")
        String images = wmNews.getImages();
        List<ImageDto> imageDtoList = JSON.parseArray(images, ImageDto.class);
        ArrayList<String> urlList = new ArrayList<>();
        for (ImageDto imageDto : imageDtoList) {
            urlList.add(imageDto.getUrl());
        }
        dto.setImages(String.join(",",urlList));
        dto.setLabels(wmNews.getLabels());
        dto.setPublishTime(wmNews.getPublishTime());
       return articleFeign.saveArticle(dto).getData();
    }

    //图片内容审核
    private boolean checkImage(WmNews wmNews) {
        boolean isPass = false;
        //图片审核包含 封面 和文章内容图片
        String coverImages =  wmNews.getImages();
        List<ImageDto> imageDtoList = JSON.parseArray(coverImages, ImageDto.class);
        //从Content中提取文本
        List<ContentDto> contentDtos =  JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {  //需要把内容图片放到imageDtoList中
            if (contentDto.getType().equals("image")) {
                ImageDto imageDto = new ImageDto();
                imageDto.setId(contentDto.getId());
                imageDto.setUrl(contentDto.getValue());
                if(!imageDtoList.contains(imageDto)){ //判断是否有重复的，如果有就不再放入了
                    imageDtoList.add(imageDto);
                }
            }
        }
        try {
            //现在的imageDtoList就是封面图片+内容图片
            List<byte[]> imageList = new ArrayList<>();
            //把图片都转成字节数组
            for (ImageDto imageDto : imageDtoList) {
                InputStream inputStream = minIOService.download(imageDto.getUrl());
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imageList.add(bytes);
            }
//            suggestion
//            pass：正常，可以直接放行。
//            review：需要进一步人工审核。             label=porn
//            block：违规，可以直接删除或者限制公开。  label=porn
            Map map = greenImageScan.imageScan(imageList);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion){
                case "pass":
                    return true;
                case "review":
                    wmNews.setStatus(3);
                    wmNews.setReason("阿里云图片审核未通过，需要人工审核，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
                case "block":
                    wmNews.setStatus(2);
                    wmNews.setReason("阿里云图片审核未通过，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    //文本内容审核
    private boolean checkText(WmNews wmNews) {
        //文本内容的审核 包含  标题  和文章的内容
        String text = wmNews.getTitle();//获取标题
        //从内容中提取文本
        List<ContentDto> contentDtos = JSON.parseArray(wmNews.getContent(),ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            //获取到的内容对比是否为text  是的话就是我们需要的内容 把这个存起来
            if (contentDto.getType().equals("text")) {
                text+=contentDto.getValue();
            }
        }
        boolean isPass =false;
        try {
            Map map = greenTextScan.greenTextScan(text);

            //把经过对对比后的结果存入到map中
            String suggestion = (String) map.get("suggestion");
//          suggestion有三种值  分别是  做个穿透  ==>  一定要 break;
//            pass：文本正常，可以直接放行。
//            review：文本需要进一步人工审核。             label=porn
//            block：文本违规，可以直接删除或者限制公开。  label=porn
            switch (suggestion) {
                case "pass": {
                    return true;
                }//直接返回
                case "review":
                    //修改自媒体文章的状态 和 未通过原因
                    wmNews.setStatus(3);
                    wmNews.setReason("阿里云文本审核未通过，需要人工审核，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
                case "block": {
                    //修改自媒体文章的状态和原因
                    wmNews.setStatus(2);
                    wmNews.setReason("阿里云文本审核未通过，原因是：" + map.get("label")); //审核不通过或需要人工审核的原因
                    wmNewsService.updateById(wmNews);
                    return false;
                }
            }} catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
